﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Kkc.Model;
using Kkc.Common;
using Kkc.Application.Specifications;
using System.ServiceModel.Syndication;
using Kkc.Application.Helpers;
using System.IO;

namespace Kkc.Application.Controllers
{
    [HandleError]
    public class AlbumController: Controller
    {
        public ActionResult Index(int? pageIndex, int? pageSize)
        {
            return View();
        }

        public ActionResult SlideShow()
        {
            return View();
        }

        public ActionResult SlideShowData()
        {
            using (var entities = new KkcDataEntities())
            {
                IQueryable<Album> query = entities.Albums.Include("Photos");

                query = query.OrderByDescending(a => a.CreationDate);

                ViewData.Model = query.ToList();
            }

            return View();
        }

        public ActionResult List(int? pageIndex, int? pageSize)
        {
            var take = pageSize ?? 10;
            var skip = take * pageIndex ?? 0;

            using (var entities = new KkcDataEntities())
            {
                IQueryable<Album> query = entities.Albums.Include("Photos");

                var specification = IocContainer.Current.Resolve<ISpecification<Album>>("published");
                query = query.Satisfy(specification);

                query = query.OrderByDescending(a => a.CreationDate);

                var list = query.Skip(skip).Take(take).ToList();

                ViewData.Model = list;
            }

            return View();
        }

        public ActionResult Feed(string format, int? pageIndex, int? pageSize)
        {
            if (!new[] { "rss", "atom" }.Contains(format))
                throw new ArgumentOutOfRangeException("format", format, "Format must be one of the allowed values. \"rss\" or \"atom\".");

            var take = pageSize ?? 10;
            var skip = take * pageIndex ?? 0;

            SyndicationFeed syndicationFeed;
            using (var entities = new KkcDataEntities())
            {
                IQueryable<Album> query = entities.Albums;

                var specification = IocContainer.Current.Resolve<ISpecification<Album>>("published");
                query = query.Satisfy(specification);

                query = query.OrderByDescending(a => a.CreationDate);

                var syndicationItems = new List<SyndicationItem>();
                foreach (var queryItem in query.Skip(skip).Take(take))
                {
                    var syndicationItem = new SyndicationItem();
                    syndicationItem.Title = TextSyndicationContent.CreateHtmlContent(queryItem.Title);
                    syndicationItem.Summary = TextSyndicationContent.CreateHtmlContent(queryItem.Summary);
                    syndicationItem.PublishDate = new DateTimeOffset(queryItem.CreationDate);
                    syndicationItem.LastUpdatedTime = new DateTimeOffset(queryItem.ModificationDate);
                    syndicationItem.Id = "/Album/feed/" + format + "/" + queryItem.Id;
                    syndicationItem.Categories.Add(new SyndicationCategory("Album"));
                    syndicationItem.Links.Add(SyndicationLink.CreateAlternateLink(new Uri(Url.Action("details", new { id = queryItem.Id }), UriKind.Relative), "text/html"));
                    syndicationItems.Add(syndicationItem);
                }

                syndicationFeed = new SyndicationFeed(syndicationItems);
                syndicationFeed.Title = TextSyndicationContent.CreatePlaintextContent("Kristiansand Karate Club - Galleri");
                syndicationFeed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri(Url.Action("index", new { pageIndex = (pageIndex ?? 0), pageSize = pageSize }), UriKind.Relative)));
                syndicationFeed.Links.Add(SyndicationLink.CreateSelfLink(new Uri(Url.Action("feed", new { pageIndex = (pageIndex ?? 0), pageSize = pageSize }), UriKind.Relative)));
                if (pageIndex > 0)
                {
                    var previous = new SyndicationLink();
                    previous.Uri = new Uri(Url.Action("feed", new { format = format, pageIndex = (pageIndex - 1), pageSize = pageSize }), UriKind.Relative);
                    previous.RelationshipType = "Previous";
                    syndicationFeed.Links.Add(previous);
                }

                if (skip + take < query.Count())
                {
                    var next = new SyndicationLink();
                    next.Uri = new Uri(Url.Action("feed", new { format = format, pageIndex = (pageIndex + 1), pageSize = pageSize }), UriKind.Relative);
                    next.RelationshipType = "Next";
                    syndicationFeed.Links.Add(next);
                }
                syndicationFeed.LastUpdatedTime = new DateTimeOffset(query.OrderByDescending(a => a.ModificationDate).Select(a => a.ModificationDate).First());
                syndicationFeed.Language = "nb-NO";
                syndicationFeed.Id = "/Album/Feed/" + format;
                syndicationFeed.Generator = "KKC Web Application";
                syndicationFeed.Description = TextSyndicationContent.CreatePlaintextContent("Denne samlingen innholder bilder fra klubben.");
                syndicationFeed.Copyright = TextSyndicationContent.CreateHtmlContent("Kristiansand Karate Club &copy; " + DateTime.Now.Year);
                syndicationFeed.Categories.Add(new SyndicationCategory("Album"));
            }

            if (string.Equals("rss", format, StringComparison.OrdinalIgnoreCase))
                return new SyndicationFeedResult(new Rss20FeedFormatter(syndicationFeed));

            return new SyndicationFeedResult(new Atom10FeedFormatter(syndicationFeed));
        }

        public ActionResult Details(int id)
        {
            using (var entities = new KkcDataEntities())
            {
                var query = from a in entities.Albums
                            where a.Id == id
                            select a;

                var album = query.FirstOrDefault();
                ViewData.Model = album;
            }

            return View();
        }

        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Edit(int id)
        {
            using (var entities = new KkcDataEntities())
            {
                var query = from a in entities.Albums
                            where a.Id == id
                            select a;

                var album = query.FirstOrDefault();
                ViewData.Model = album;
            }

            return View();
        }

        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, string title, string summary)
        {
            using (var entities = new KkcDataEntities())
            {
                var query = from a in entities.Albums
                            where a.Id == id
                            select a;

                var album = query.First();
                album.Title = title;
                album.Summary = summary;
                entities.SaveChanges();
            }

            return RedirectToAction("Details", new { Id = id });
        }

        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Create()
        {
            return View();
        }

        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(string title, string summary)
        {
            using (var entities = new KkcDataEntities())
            {
                var album = new Album();
                album.Title = title;
                album.Summary = summary;
                entities.AddToAlbums(album);
                entities.SaveChanges();
                entities.Refresh(System.Data.Objects.RefreshMode.StoreWins, album);
                return RedirectToAction("Details", new { Id = album.Id });
            }

        }

        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Import()
        {
            return View();
        }

        [Authorize(Roles = "Contributor")]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Import(string title, string summary)
        {
            using (var entities = new KkcDataEntities())
            {
                var album = new Album();
                album.Title = title;
                album.Summary = summary;
                entities.AddToAlbums(album);
                entities.SaveChanges();
                entities.Refresh(System.Data.Objects.RefreshMode.StoreWins, album);

                var directoryInfo = new DirectoryInfo(Server.MapPath("~/App_Data/Import"));
                foreach (var fileInfo in directoryInfo.GetFiles())
                {
                    if (!new[] { ".jpeg", ".jpg", ".png", ".gif" }.Contains(fileInfo.Extension, StringComparer.OrdinalIgnoreCase))
                        continue;

                    var photo = new Photo();
                    photo.Title = "Ingen tittel";
                    photo.Summary = "Ingen beskrivelse";
                    photo.Album = album;

                    var file = new Model.File();
                    file.ContentType = "image/"+fileInfo.Extension.Substring(1);
                    file.Filename = Path.GetFileName(fileInfo.Name);
                    file.Contents = System.IO.File.ReadAllBytes(fileInfo.FullName);
                    file.ContentLength = file.Contents.Length;
                    var md5 = System.Security.Cryptography.MD5.Create();
                    var hash = md5.ComputeHash(file.Contents, 0, file.Contents.Length);

                    var checksumBuilder = new StringBuilder();
                    foreach (var digit in hash)
                    {
                        checksumBuilder.AppendFormat("{0:x2}", digit);
                    }
                    file.Checksum = checksumBuilder.ToString();

                    photo.File = file;
                    entities.AddToPhotos(photo);
                    entities.SaveChanges();
                    fileInfo.Delete();
                }
                return RedirectToAction("Details", new { Id = album.Id });
            }

        }
    }
}
